home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Library
/
RoseWare - Network Support Library.iso
/
apidev
/
apiasm.exe
/
API.ASM
Wrap
Assembly Source File
|
1992-08-09
|
45KB
|
1,368 lines
;--------------------------------------------------
;
; JX
;
;--------------------------------------------------
comment #
keywords: CXI API POPUP ASM
SAMPLE asm source code for a popup interface between a
pc user and a mainframe coax-connected host, via the CXI API.
This allows a program to process screens and keys before
passing them through. Uploaded as a self-extracting EXE.
Unlike simpler programs, this type of program in active thoughout
the session, and must continually keep the screen updated while
passing along translated keystrokes to the host when the host
is not busy. A reset can be sent while the host is busy.
This is not a working program. Code which was specific to the
original application has been removed. The original program
provided allowed a mainframe reporting program to print directly
on the pc using specially formatted screens.
The current hotkey is both shift keys together.
The 'outkb' routine is untested on 8088 machines...
See the cautions marked by double-semi flags (';;')
#
;-------------------------------------------------
;bios seg
bios_seg segment at 40h
org 17h
kbflag db ?
org 1Ah
kbhead dw ? ;buffer head
kbtail dw ? ;buffer tail
kbbuf dw 16 dup (?) ;orig\only buf
org 63h
addr_crtc dw ? ;crtc base
org 87h
ega_info db ? ;ega info byte
bios_seg ends
;-------------------------------------------------
code segment para public 'code'
assume cs:code, ds:code
org 100h
begin: jmp install
db 'JX 01- cxi screen capture'
;--------------------------------------------------
adapter db 0
apicall equ <int 111> ;"saves only cs,ds,es,bp,ss,sp"
areasw db 0
bioseg dw 40h
busy10 db 0
busy13 db 0
critaddr dw 0
crtc dw 0
cseg dw 0
curloc dw 0
curloc2 dw 0
curpos2 dw 0
curtyp2 dw 0
dataloc dw 0 ;bufloc for data start
dos_seg dw 0 ;seg of internal dos flags
dos_version dw 0 ;dos version number
indosaddr dw 0 ;offset of indos flag
jxactive db 0
kbstart dw 0
kbend dw 0
muxid equ 44
mypsp dw 0
my_style dw 0
oldint8 dw 0,0 ;tik
oldint9 dw 0,0 ;kb
oldint28 dw 0,0 ;idle
oldint2f dw 0,0 ;mux
pop_request db 0
popped db 0
popoutsw db 0
prevscan db 0,0
resetsw db 0
savess dw 0 ;must be in cs:
savesp dw 0 ;"
tmodd dw 0,0
uninsw db 0
unloadsw db 0
vid_page db 0
vidseg dw 0
;..................................................
;aid keys
aidlist db 105, 112, 113 ;clr, pa1, pa2
;pf1-24
db 120,121,122,123,124,126,126,127,128,129,130,131
db 133,134,135,136,137,138,139,140,141,142,143,144
aidlistlen equ $-aidlist
;------------------------------------------------------------
;bug on some 286s:
;if ints are disabled and the flags on the stack are also
;disabled, a popf may allow one int after the popf
;Use this macro instead
popff macro
push cs
call iiret ;any iret
endm
;..................................................
;long 'jmp if equal'
jmpe macro x
local tt
jne tt
jmp &x
tt:
endm
;..................................................
jmpne macro x
local tt
je tt
jmp &x
tt:
endm
;..................................................
mypusha macro
irp x, <ax, bx, cx, dx, di, si, ds, es, bp>
push x
endm
endm
;.............................................................
mypopa macro
irp x, <bp, es, ds, si, di, dx, cx, bx, ax>
pop x
endm
endm
;..........................................................
esds macro
push ds
pop es
endm
;..........................................................
;load literal addr with inline constant
laddr macro r, l
local tt
mov &r, offset $ +5
jmp short tt
db &l
tt:
endm
;--------------------------------------------------
;--------------------------------------------------
restart:
;popup entry point- after lo-level activation
esds ;set es=ds
call pushscr2 ;save screen
call clrscr ;clear screen
mywait:
;idle loop entry point
int 28h ;idle call dos
cmp popoutsw, 0 ;hotkey back to dos
je @f ;no
mov popoutsw, 0
jmp popout
@@:
call paint ;updt display buffer or print
;process reset key, without testing for busy host
cmp resetsw, 0
je ss40 ;none
mov resetsw, 0
mov ax, resetkey ;send
call emit
call clr_kb ;clear all pending keystrokes
jmp mywait
ss40:
;process non-aid keys, without testing for busy host
call tstkey ;see next key waiting
jz mywait ;none
cmp al, 13 ;enter
je ss60 ;yes- aid
or al, al ;extended
jnz @f ;no- not aid
mov di, offset aidlist ;search for key in aid list
xchg ah, al
mov cx, aidlistlen
esds
repne scasb ;scan
xchg ah, al ;restore
je ss60 ;is aid - wait for unlock
@@:
;not aid
call getkey ;dequeue the key
cmp al, '~' ;uninstall
je @f ;yes
call emit ;send to buffer
jmp ss40 ;get next key
@@:
;uninstall
call ckvec ;are we last on all vectors
jnc @f ;yes
mov al, 7 ;beep
int 29h
jmp mywait
@@:
mov unloadsw, 1
mov popped, 0 ;allow recursive pop
jmp popout
ss60:
;aid key pending
;if we are busy, trash the key
call tstlok ;kb locked
jc ss66 ;yes
mov ax, 3 ;wait n/18ths second to be sure
call delayx
mov ax, 11 ;updt buffer
apicall
call tstlok ;still unlocked
jc ss66 ;no
call getkey ;dequeue aid key
call emit ;send it
jmp mywait
ss66:
call getkey ;get aid key
jmp mywait ;ignore it
;--------------------------------------------------
paint:
;updt buffer
;updt 3278 buffer
mov ax, 11 ;updt buffer
apicall
;paint screen
mov ax, 10 ;paint screen
apicall
;set cursor
call tstlok ;unless locked
jnc @f
ret ;locked
@@:
mov ax, 4 ;get cursor addr
apicall
mov curloc2, ax ;painted cursor abs loc
mov dx, ax ;convert to row,col
mov ax, 26
apicall
cmp ax, 26 ;no cxi connection
jne @f
mov ax, 0101h ;true
@@:
mov dx, ax ;row,col
dec dh ;relative
dec dl ;relative
call curpos
ret
;--------------------------------------------------
tstlok:
;stc if kb is locked
;busy indicator is statline pos 9 = X
mov ax, 5 ;read buf char
mov dx, 8 ;pos 9
apicall
cmp al, 'X'
je lokt
clc ;unlocked
ret
lokt:
stc ;locked
ret
;--------------------------------------------------
emit:
;send al char to interface
mov dx, ax
xor dh, dh ;assume non-extended
or al, al
jnz @f ;true
inc dh
mov dl, ah
@@:
mov ax, 6 ;emit key
apicall
ret
;--------------------------------------------------
get_kb:
call getkey
jz get_kb ;no key avail
ret
;..................................................
clr_kb:
call getkey
jnz clr_kb
ret
;..................................................
tstkey:
mov ah, 1 ;any key waiting
int 16h
jne @f ;yes
xor ax, ax ;zr
@@: ret
;..................................................
getkey:
;return key or zr
mov ah, 1 ;any key waiting
int 16h
jne @f ;yes
ret
@@:
mov ah, 0 ;get key
int 16h
cmp ax, 1515h ;special prefix
jne gk20 ;no
mov ah, 1 ;2nd key waiting
int 16h
je getkey ;no- discard
mov ah, 0 ;get 2nd key
int 16h
xchg ah, al ;reformat it
gk20:
cmp al, 0e0h ;ext key
je getkey ;yes- ignore
or ax, ax ;nz
ret
;--------------------------------------------------
pushscr2:
;save user's screen in alternate page ;;
xor si, si
mov di, si
add di, 4096 ;store in page 2
mov cx, 4096/2
mov es, vidseg
push ds
mov ds, vidseg
rep movsw
pop ds
esds
mov ah, 3 ;get pos and style
mov bh, vid_page
int 10h
mov curpos2, dx
cmp cl, 0 ;style with emulation disabled
je @f ;yes
cmp cl, 7
ja @f ;yes
or cx, 80h ;flag to reset with emulation
@@:
cmp adapter, 0 ;mono
jne @f ;no
mov cx, 0b0ch
@@:
mov curtyp2, cx
ret
;..................................................
popscr2:
mov es, vidseg
xor di, di
mov si, di
add si, 4096
mov cx, 4096/2
push ds
mov ds, vidseg
rep movsw
pop ds
esds
mov dx, curpos2
call curpos
mov cx, curtyp2
call show_cx_cursor
ret
;--------------------------------------------------
;--------------------------------------------------
;KEYBOARD INTERRUPT HANDLER
;remap keys for 3270 functions
;f1-12 --> pf1-12
;alt 1-= pf1-12
;ctl f1-12 pf13-24
;ctl 1-= pf13-24
;alt f9 pa1
;alt f10 pa2
;alt f11 pa3
;esc clear
;bsp,enter,tab,up,down,left,right,ins,del == same
;end reset
;home deleof
;shift tab backtab
;ctl tab backtab
;ctl enter newline
;.................................................
;0= transparent
;1= ignore
plaintbl:
dw 6900h ;1 esc -> clear
dw 58-2+1 dup(0) ;2-58 are transparent
dw 7800h, 7900h ;59-68 f1-f10
dw 7a00h, 7b00h ;f3-4
dw 7c00h, 7d00h ;f5-6
dw 7e00h, 7f00h ;f7-8
dw 8000h, 8100h ;f9-10
dw 70-69+1 dup(0) ;69-70 transparent
dw 4000h ;71 home -> deleof
dw 0 ;72 up
dw 1 ;73 pgup null
dw 0 ;74 -
dw 0 ;75 left
dw 1 ;76 center -> null
dw 0 ;77 right
dw 0 ;78 +
resetkey dw 4f00h ;79 end -> reset
dw 0 ;80 down
dw 1 ;81 pgdn -> null
dw 0 ;82 ins
dw 0 ;83 del
dw 86-84+1 dup(1) ;84-86 -> null
dw 8200h, 8300h ;87-88 f11,12
;.................................................
ctltbl:
dw 0 ;1=esc (Windows)
dw 8500h, 8600h ;2-13 (digits-=) -> pf13-24
dw 8700h, 8800h
dw 8900h, 8a00h
dw 8b00h, 8c00h
dw 8d00h, 8e00h
dw 8f00h, 9000h
dw 0 ;14 bsp
backtab dw 0f00h ;15 ^tab -> backtab
dw 27-16+1 dup(0) ;16-27
dw 4e00h ;28 enter -> newline
dw 58-29+1 dup(0) ;29-58
dw 8500h, 8600h ;59-68 f1-10 -> pf13-22
dw 8700h, 8800h ;
dw 8900h, 8a00h ;
dw 8b00h, 8c00h ;
dw 8d00h, 8e00h ;
dw 86-69+1 dup(1) ;69-86
dw 8f00h, 9000h ;87-88 f11,12 -> pf23,24
;.................................................
alttbl:
dw 1 ;1 esc -> null
dw 7800h, 7900h ;2-13 (digits-=) -> pf1-12
dw 7a00h, 7b00h
dw 7c00h, 7d00h
dw 7e00h, 7f00h
dw 8000h, 8100h
dw 8200h, 8300h
dw 27-14+1 dup(0) ;14-27
dw 4e00h ;28 enter -> newline
dw 66-29+1 dup(0) ;29-66
dw 7000h ;67-69 f9 pa1
dw 7100h ; f10 pa2
dw 7200h ; f11 pa3
dw 88-70+1 dup(1) ;70+
;-------------------------------------------------
;check table len
if ($-plaintbl) / 2 - (3*88)
.err
endif
;--------------------------------------------------
;--------------------------------------------------
newint9:
;kb int handler
cli
pushf
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
push bp
mov ds, cs:cseg
;fix bios bug
mov al, 0adh ;disable kb
call outkb
sti ;enable higher ints
in al, 60h ;get scancode
jmp $+2
mov ah, prevscan +1 ;prev key
mov prevscan, ah
mov prevscan+1, al ;this key
xor ah, ah
test al, 80h ;break etc.
jmpne jbios ;yes- ignore
;get shift state
mov es, bioseg
mov cl, es:kbflag
;test for hotkey
cmp al, 42 ;left-shift
jne @f ;no
test cl, 1 ;right-shift pending
jnz hotyes ;yes
jmp short jbios
@@:
cmp al, 54 ;right-shift
jne nothot ;no
test cl, 2 ;left shift pending
jz jbios ;no
hotyes:
;hotkey pressed
cmp jxactive, 0 ;active
jne @f ;yes
mov pop_request, 18 ;pop
jmp done9
@@:
inc popoutsw
jmp done9
nothot:
cmp jxactive, 0 ;are we active
je jbios ;no- done
;passthru if numlok+ keypad (digit)
test cl, 20h ;numlok on
jz @f ;no
cmp prevscan, 0e0h ;extended (negates numlok)
je @f ;yes
cmp al, 71 ;keypad
jb @f ;no
cmp al, 83
jna jbios ;yes- transparent
@@:
;the only shift translation is shift-tab to backtab.
test cl, 3 ;shifted
jz noshift ;no
cmp al, 15 ;tab
jne jbios ;no
mov bx, backtab
jmp short stuff_bx
noshift:
;set bx to correct shift-state lookup tbl
mov bx, offset plaintbl ;assume no state
test cl, 8 ;alt mask
jz noalt ;no
mov bx, offset alttbl
noalt:
test cl, 4 ;ctl mask
jz @f ;no
mov bx, offset ctltbl
@@:
;get replacement char
mov si, ax
shl si, 1
mov bx, [bx] [si] -2 ;fetch replacement
cmp bx, 1 ; 0=transparent (pass to bios)
je done9 ; 1=nul
ja stuff_bx ; else replace
jbios:
;pass to bios
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
call dword ptr cs:oldint9
push ax
mov al, 0aeh ;enable kb
call outkb
pop ax
iret
stuff_bx:
cmp bx, resetkey ;reset key
jne @f ;no
inc resetsw ;set priority switch
jmp short done9 ;ignore key
@@:
mov ax, bx
cmp bh, 83h ;bios max
jna @f
push bx
mov ax, 1515h ;special prefix code (see getkey)
call stuffchar ;(does sti)
pop ax
xchg ah, al ;reversed extended code
@@:
call stuffchar ;(does sti)
done9:
pop bp
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
cli
;enable kb
mov al, 0aeh ;enable kb
call outkb
;clear kb int
in al, 61h
jmp $+2
or al, 80h
out 61h, al ;set hi
jmp $+2
and al, not 80h
out 61h, al ;set lo
jmp $+2
;eoi
mov al, 20h
out 20h, al
jmp $+2
pop ax
popf
iret
;--------------------------------------------------
outkb:
;this helps avoid a bios bug
push ax
@@: in al, 64h
jmp $+2
test al, 2
jnz @b
pop ax
out 64h, al
jmp $+2
ret
;--------------------------------------------------
stuffchar:
;stuff ax into kbbuf
;es = bios
cli
mov bx, es:kbtail ;next open loc
add bx, 2 ;new tail
cmp bx, kbend ;wrap
jne @f ;no
mov bx, kbstart
@@: cmp bx, es:kbhead ;new tail = head
je @f ;yes- no room for more- abandon
xchg es:kbtail, bx ;new tail
mov es:[bx], ax ;add char
@@:
sti
ret
;-----------------------------------------------------------
delayx:
;delay ax tiks. (55ms, 18.2 tiks per second)
call start_tmo
@@: call tst_tmo
jnc @b
ret
;------------------------------------------------------------
start_tmo:
;initialize tmo counter
push ax
push es
mov es, bioseg
mov ax, es:[6ch] ;timer lo
mov tmodd, ax
mov ax, es:[6eh] ;timer hi
mov tmodd +2, ax
pop es
pop ax
ret
;------------------------------------------------------------
tst_tmo:
;stc if ax tiks have elapsed since last call to start-tmo
push ax
push bx
push cx
push dx
mov bx, ax
push es
mov es, bioseg
mov cx, es:[6ch] ;timer lo
mov ax, es:[6eh] ;timer hi
pop es
;get init-val plus interval
mov dx, tmodd +2 ;hi
add bx, tmodd
jnc @f ;no lo wrap
add dx, 1 ;(don't inc)
jnc @f ;no num wrap
;deadline is a wrap.
cmp dx, ax ;deadline, current hi
jne timex ;no timeout
cmp bx, cx ;deadline, current lo
ja timex
jmp short timeout ;timeout
@@: cmp dx, ax ;deadline, current hi
ja timex ;no timeout
cmp bx, cx ;lo
ja timex ;no timeout
timeout:
stc
jmp short timez
timex:
clc
timez:
pop dx
pop cx
pop bx
pop ax
ret
;--------------------------------------------------
clrscr:
xor dx, dx
call curpos
mov cx, 25*80
jmp short clr_area
;.....................................
clr_area:
;write cx blanks at dx
push es
push cx
call get_dxaddr
pop cx
mov al, ' '
inc areasw
call vidchar
pop es
ret
;--------------------------------------------------
show_cx_cursor:
cmp adapter, 2 ;ega active
jne @f ;no
test cx, 80h ;use ega emulation
jnz @f ;yes
push es
mov es, bioseg
push word ptr es:ega_info ;save ega info byte
or byte ptr es:ega_info, 1 ;disable ega cursor emulation
mov ah, 1 ;set cx cursor style
int 10h
pop word ptr es:ega_info ;restore ega info byte
pop es
ret
@@:
and cx, not 80h
mov ah, 1 ;set cx cursor style
int 10h
ret
;--------------------------------------------------
curpos:
;set real and virtual cursor pos from dx
mov curloc, dx
push ax
push bx
mov ah, 2 ;set dx pos
mov bh, vid_page
int 10h
pop bx
pop ax
ret
;--------------------------------------------------
tty2:
;write al char at curloc. bump curloc.
;preserve all regs
push ax
push cx
push di
push si
push es
;compute buffer offset
push ax ;char
call get_vidaddr
pop ax
call vidchar ;store
inc curloc
cmp byte ptr curloc, 80
jb @f
mov byte ptr curloc, 0
inc byte ptr curloc+1
@@: pop es
pop si
pop di
pop cx
pop ax
ret
;--------------------------------------------------
get_dxaddr:
mov curloc, dx
get_vidaddr:
;curloc to es:di
push ax
push cx
mov al, byte ptr curloc+1 ;line x 160
mov cx, 160
mul cl
mov cl, byte ptr curloc ;col x 2
shl cl, 1
add ax, cx ;offset in page
xor di, di
cmp ax, 25*160 ;4,000
ja @f
mov di, ax ;to
@@: mov cl, vid_page
jcxz @f ;save time
mov ax, 1000h ;4k pages in 80 col mode
mul cl ;page offset
add di, ax ;total offset
@@: mov es, vidseg
pop cx
pop ax
ret
;--------------------------------------------------
vidchar:
stosb
inc di
cmp areasw, 0
je @f
dec cx
jnz vidchar
mov areasw, cl
@@: ret
;--------------------------------------------------
;--------------------------------------------------
;timer and popup
assume ds:nothing ;for ints and popup
newint8:
;timer int
cli
pushf
call dword ptr oldint8 ;also does eoi
cmp popped, 0 ;is anybody pending or popped
je @f ;no
iret
@@: inc popped ;busy now
sti
cld
;regs have not been saved
cmp unloadsw, 2 ;unloading
je @f ;yes
cmp pop_request, 0 ;pop requested
je exit8 ;no
@@:
cmp busy10, 0 ;video busy
jne bad8 ;yes- exit with prejudice
cmp busy13, 0 ;disk busy
jne bad8 ;yes- exit with prejudice
push es
push di
mov es, dos_seg ;indos seg (usually)
mov di, indosaddr
cmp byte ptr es:[di], 0 ;dos busy
jne xp ;yes- exit with prejudice
mov di, critaddr ;in critical error
cmp byte ptr es:[di], 0
jne xp ;yes- exit with prejudice
mov pop_request, 0
call popup
mov pop_request, 1 ;going to 0
xp:
pop di
pop es
bad8:
dec pop_request
exit8:
cli
mov popped, 0
iret
;-----------------------------------------------------------------------
;assume ds:nothing ..cont
newint28:
;idle int
;note regs are not saved until popup
cli
pushf
call dword ptr oldint28
cmp popped, 0 ;is anybody popped
je @f ;no
iret
@@: inc popped ;busy now
sti
cld
cmp pop_request, 0 ;pop requested
je exit28 ;no- exit
cmp busy10, 0 ;video busy
jne exit28 ;yes- exit
cmp busy13, 0 ;disk busy
jne exit28 ;yes- exit
push es
push di
mov es, dos_seg ;in critical error
mov di, critaddr
cmp byte ptr es:[di], 0
pop di
pop es
mov pop_request, 0
jne exit28 ;yes
call popup
exit28:
cli
mov popped, 0
iret
;-----------------------------------------------------------
;assume ds:nothing ..cont
popup:
mov savess, ss ;save caller's stack
mov savesp, sp
cli ;new stack
push cs
pop ss
mov sp, offset stackend
sti
mypusha
;.........................................................
mov ds, cs:cseg
assume ds:code ; es is not set
;.........................................................
;test for uninstall
cmp unloadsw, 2
jne @f ;no
esds
call remove ;disable and unvector
mov es, mypsp
mov cx, es:[2ch] ;envir blok
push cx ;save
mov ah, 49h ;release pgm
mov es, mypsp
int 21h
pop es ;envir
mov ah, 49h ;release envir
int 21h
jmp short popexit
@@:
call ck_vid ;mode ok to pop
jnc pop20 ;yes
;................
popexit:
;return to interrupted application
cmp unloadsw, 1
jne @f
inc unloadsw
@@:
mypopa
mov ss, cs:savess
mov sp, cs:savesp
ret ;back to int8,int28
;................
pop20:
;we are active
inc jxactive ;we're active
esds
jmp restart
;.....................................................
popout:
;return to interrupted pgm (jumped-to)
call popscr2 ;restore as when called
call clr_kb
mov jxactive, 0
jmp popexit
;-----------------------------------------------------------
newint2f:
; entry: ah - device id
pushf
cmp ah, muxid
je @f ;its us
popff
jmp dword ptr cs:oldint2f
@@:
push ds
push cs
pop ds
mov al, -1 ;indicate installed
cmp bx, 0202h ;called to pop (nu)
jne @f ;no
mov pop_request, 26
@@:
cmp bx, 0303h ;called to uninstall
jne fx ;no
call ckvec ;are we last on all vectors
jnc @f ;yes
mov al, 7 ;beep
int 29h
jmp short fx
@@: mov unloadsw, 2
fx:
push cs ;returns es = installed segment
pop es
pop ds
popff
iiret: iret
;---------------------------------------------------------
ckvec:
;stc if any ints have been intercepted since we loaded
mov al, 8
call cksub
jne @f
mov al, 9
call cksub
jne @f
mov al, 28h
call cksub
jne @f
mov al, 2fh
call cksub
jne @f
clc
ret
@@:
stc
ret
;.........................................................
cksub:
push es
mov ah, 35h
int 21h
mov ax, es
cmp ax, cseg
pop es
ret
;---------------------------------------------------------
remove:
push ds
assume ds:nothing
lds dx, dword ptr oldint8
mov ax, 2508h
int 21h
lds dx, dword ptr oldint9
mov ax, 2509h
int 21h
lds dx, dword ptr oldint28
mov ax, 2528h
int 21h
lds dx, dword ptr oldint2f
mov ax, 252fh
int 21h
pop ds
assume ds:code
ret
;------------------------------------------------------------
ck_vid:
mov ah, 0fh
int 10h ;get cols,mode,page
cmp al, 2 ;2,3,7 ok (all are 80 col)
je @f
cmp al, 3
je @f
cmp al, 7
je @f
stc ;no
ret
@@: mov vid_page, bh
clc
ret
;------------------------------------------------------------
;------------------------------------------------------------
;final section of resident code
;this allocation method minimizes the .com size
even
mystack equ $ ;stack 512
stackend equ mystack +512 -2
progend equ mystack +512
;------------------------------------------------------------
install:
;end of resident code
;one-time init code
mov ax, cs
mov ds, ax
mov mypsp, es
mov es, ax
mov ss, ax
mov sp, offset stackend
mov cseg, ax
cld
call getcmd ;get cmdline parms
cmp uninsw, 0 ;request to uninstall
je @f ;no
mov ah, muxid
xor al, al
mov bx, 0303h
int 2fh
mov ax, 4c00h ;eoj
int 21h
@@:
call getvid ;get display info
call revec ;setup intercepts
;get dos version
mov ah, 30h
xor al, al
int 21h
xchg ah, al
mov dos_version, ax
;set kbstart,end
mov ax, offset kbbuf
mov bx, offset kbbuf+32
mov kbstart, ax
mov kbend, bx
;get cursor offset for 2,2
;(first char of each line is an attrib char)
mov ax, 25 ;convert row,col to offset
mov dh, 2
mov dl, 2
apicall
mov dataloc, ax ;save
;display msg
mov ah, 9
laddr dx, <'JX Installed.$'>
int 21h
;adj pgm size
mov ax, 4a00h
mov bx, (progend-code +15) shr 4
mov es, mypsp
int 21h
;go resident
mov ax, 3100h ;tsr
mov dx, (progend-code +15) shr 4
int 21h
;--------------------------------------------------
getvid:
;get video segment addr
;set adapter type
mov es, bioseg
mov ax, es:addr_crtc
mov crtc, ax
mov ah, 12h ;get ega,vga info
mov bl, 10h
int 10h
cmp bl, 10h ;did bl return unchanged
je vid20 ;yes- no ega,vga
mov es, bioseg
test es:ega_info, 8 ;ega currently active
jnz vid20 ;no
mov adapter, 2 ;active ega
mov vidseg, 0b800h ;color
push bx
mov ax, 1130h ;get nof scan lines per char
int 10h ;to create new shape
dec cl
mov ch, cl
sub ch, 2
mov my_style, cx
pop bx
or bh, bh ;ega attached to color monitor
je vid40 ;yes
mov vidseg, 0b000h ;mono
jmp short vid40
;cga or mda.
vid20: test crtc, 40h ;mono
jz @f ;yes
mov adapter, 1 ;cga
mov my_style, 0607h
mov vidseg, 0b800h ;color
jmp short vid40
@@: mov adapter, 0 ;mda
mov my_style, 0b0ch
mov vidseg, 0b000h ;mono
vid40:
esds
ret
;--------------------------------------------------
revec:
;see if already resident in memory. dos 3.0+ only
not word ptr [begin] ;no match on this copy
mov ah, muxid
xor al, al
int 2fh ;sets es = installed seg
or al, al
jz nodup ;not found
mov si, offset begin ;tst signature also
mov di, si
mov cx, 16
repe cmpsb
jne nodup
laddr dx, <'Already installed$'>
mov ah, 9
int 21h
mov ax, 4c01h ;eoj
int 21h
;.....................
nodup:
;get dos-seg and indos addr at es:bx
mov ah, 34h
int 21h
mov dos_seg, es
mov indosaddr, bx
;get critical err addr
mov ax, 3e80h ;cmp opcode
mov cx, 2000h ;max search length
mov di, bx ;start at indos address
@@: repne scasw ;do the search
jcxz @f ;branch if search failed
cmp byte ptr es:[di+5], 0bch ;verify this is it
je found ;yes
jmp @b
@@: mov cx, 2000h ;search again
inc bx ;search odd addresses this time
mov di, bx
@@: repne scasw ;look for the opcode
jcxz @f ;not found
cmp byte ptr es:[di+5], 0bch ;verify
je found
jmp @b
@@:
laddr dx, <'DOS flag not found$'>
mov ah, 9
int 21h
mov ax, 4c01h
int 21h
nop
found: mov ax, es:[di] ;get flag offset address
mov critaddr, ax
;.....................
mov ax, 3508h ;timer tik
int 21h
mov oldint8, bx
mov oldint8 +2, es
mov ax, 2508h
mov dx, offset newint8
int 21h
mov ax, 3509h ;kb int
int 21h
mov oldint9, bx
mov oldint9 +2, es
mov ax, 2509h
mov dx, offset newint9
int 21h
mov ax, 3528h ;idle
int 21h
mov oldint28, bx
mov oldint28 +2, es
mov ax, 2528h
mov dx, offset newint28
int 21h
mov ax, 352fh ;multiplex
int 21h
mov oldint2f, bx
mov oldint2f +2, es
mov ax, 252fh
mov dx, offset newint2f
int 21h
esds
ret
;----------------------------------------------------------
;..revector
getcmd:
;cmd tail tests
assume ds:nothing
mov ds, mypsp
;.............
;test for cmdline /U to uninstall
mov si, 81h
@@: lodsb
cmp al, 13
je @f
or al, 20h
cmp al, 'u'
jne @b
cmp byte ptr [si-2], '/'
jne @b
inc uninsw
@@:
;.............
mov ds, cs:cseg
assume ds:code
ret
;------------------------------------------------------------
code ends
end begin